package com.lzy.cloud.ticket.admission.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;

import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SignUtil {

    private static final String API_SIGNATURE_KEY ="sign" ;

    /**
     * 根据入参和密钥获取签名
     * @param data
     * @param secretKey
     * @return
     * @throws Exception
     */
    // 第一步：获取所有值非空的参数，忽略签名
    public static String getSignature(JSONObject data, String secretKey) throws Exception {
        List<String> keyList = new ArrayList<String>();
        for (Object key : data.keySet()) {
            // key为null或者key是签名
            if (key == null || API_SIGNATURE_KEY.equalsIgnoreCase(key.toString())) {
                continue;
            }
            // value为null或者为空
            if (data.get(key) == null || StringUtils.isBlank(data.get(key).toString())) {
                continue;
            }
            keyList.add(key.toString());
        }
        // 第二步：按名称排序并拼接成字符串
        String[] arrayToSort = keyList.toArray(new String[keyList.size()]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder(secretKey);
        for (String key : arrayToSort) {
            sb.append(key);
            sb.append(data.get(key));
        }
        sb.append(secretKey);

        //log.info("获取签名方法，生成签名第二步结果为" + sb.toString());
        // 第三步：MD5加密并转换成大写的16进制
        MessageDigest md = MessageDigest.getInstance("MD5");
        return byte2hex(md.digest(sb.toString().getBytes()));
    }

    private static String byte2hex(byte[] bytes) {
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex.toUpperCase());
        }
        return sign.toString();
    }

    public static void main(String[] args) throws Exception {
        JSONObject map = new JSONObject();
        map.put("apiKey", "tickettest");//api秘钥
        map.put("timestamp", "2015-09-16 13:01:25");//时间戳
        map.put("agencyProductId", "11402");//产品代理id
        map.put("planDateStr", "2015-11-01");//计划日期字符串

        String signature = getSignature(map, "S5QquHJceY1es5ItyQxV");//秘钥
        map.put(API_SIGNATURE_KEY,signature);

        System.out.println(map.toString());
    }
}
